// PartFormatManager.cpp: implementation of the PartFormatManager class.
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "PartFormatManager.h"
#include "PartFormat.h"
#include "ProductCatalog.h"
#include "RecordsetPtrWrap.h"
#include "DBConnectionManager.h"
#include "Global.h"
#include "user.h"
#include "DataSourceManager.h"
#include "Standard.h"
#include "OriginalPropertySet.h"
#include "SimpleExpression.h"

using namespace Global;
using namespace DAWrapper;
using namespace JointSystem;
using namespace PropertySystem;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

DSItemManager::DSItemManager( PartFormatManager* pfm )
{
	Initialize( pfm );
}

bool DSItemManager::Initialize( PartFormatManager* pfm )
{
	assert( pfm );
	assert( pfm->DataSourceConnection() );

	RecordsetPtrWrap rs;
	CString strQuery( _T( "SELECT * FROM Part_Format" ) );
	if ( FAILED( rs.Set( strQuery, *pfm->DataSourceConnection() ) ) ) return false;
	if ( rs.GetRecordCount() == 0 ) return false;

	while ( !rs.IsEOF() )
	{
		DSItem* pf = new DSItem;
		pf->FormatName( rs.GetString( _T( "ID" ) ) );
		pf->LegalCondition(rs.GetString( _T("Legal_Condition")));
		CString str( rs.GetString( _T( "Script_URI" ) ) );
		pf->Uri( pfm->Owner()->StandardDir() + str );
		pf->BmpName(rs.GetString(_T("Bmp_Name")));
		pf->Connection( pfm->DataSourceConnection() );
		this->Add(pf->FormatName(), pf);
		rs.MoveNext();
	}
	return true;
}

DSItemManager::~DSItemManager()
{
}

DSItemManager::Iterator* DSItemManager::GetItem( const CString& pfid )
{
	return this->GetManaged(pfid);
}

namespace JointSystem
{

PartFormatManager::PartFormatManager( ProductCatalog* owner )
{
	m_Owner = owner;
	m_DSConn = 0;
	m_DSManager = 0;
}

PartFormatManager::~PartFormatManager()
{
	if ( m_DSManager ) delete m_DSManager;
}

_ConnectionPtr* PartFormatManager::DataSourceConnection()
{ 
	return m_DSConn ? m_DSConn :
	m_DSConn = DBConnectionManager::Instance()->GetConnectionPtrByUri( Owner()->DataSourceURI() );
 }

DSItemManager* PartFormatManager::GetDSItemManager()
{
	return m_DSManager ? m_DSManager :
		m_DSManager = new DSItemManager( this );
}

DSItemManager::Iterator* PartFormatManager::GetDSItem( const CString& pfid )
{
	return GetDSItemManager()->GetItem( pfid );
}

PartFormat* PartFormatManager::GetPartFormat( const CString& partFormatID )
{
	PartFormat* pf = GetManaged(partFormatID);
	if(pf != NULL)
		return pf;
	if ( DataSourceConnection() == 0 ) return 0;

	pf = new PartFormat( this );
	ASSERT_MEMORY_VALID(pf, NULL);
	pf->ID(partFormatID);
	Add( partFormatID, pf );

	return pf;
}

PropertiesOfProductFormat* PartFormatManager::GetProperties( const CString& aPartFormatID )
{
	PartFormat* pf = GetPartFormat( aPartFormatID );
	if ( pf == 0 ) return 0;

	PropertiesOfProductFormat* ufopf = pf->Properties();
	if ( ufopf ) return ufopf;

	CString strSource;
	strSource.Format( _T( "SELECT * FROM Product_Property WHERE PF_ID=\'%s\' " ), aPartFormatID );
	RecordsetPtrWrap rs;	
	
	if ( FAILED( rs.Set( strSource, *DataSourceConnection() ) ) ) return 0;
	if ( rs.GetRecordCount() == 0 ) return 0;
	
	ProductFormatProperty* uf = 0;
	ufopf = new PropertiesOfProductFormat;
	while ( !rs.IsEOF() )
	{
		uf = new ProductFormatProperty;
		uf->Type( (ProductPropertyType)rs.GetInt( _T( "Type_ID" ) ) );
		uf->DefaultValue( rs.GetString( _T( "Default_Value" ) ) );
		uf->Description( rs.GetString( _T( "Description" ) ) );
		ufopf->SetAt( rs.GetString( _T( "Name" ) ), uf );
		uf = 0;
		rs.MoveNext();
	}
	pf->Properties( ufopf );
	return ufopf;
}

JointPortFormersOfPartFormat* PartFormatManager::GetJointPortFormers( const CString& aPartFormatID )
{
	PartFormat* pf = GetPartFormat( aPartFormatID );
	if ( pf == 0 ) return 0;

	JointPortFormersOfPartFormat* jpfopf= pf->JointPortFormers();
	if ( jpfopf ) return jpfopf;
	
	ASSERT(Owner());
	ASSERT(Owner()->GetStandard());

	CString strSource;
	strSource.Format( _T( "SELECT * FROM %s WHERE PF_ID=\'%s\' order by [order]" ),
		Owner()->GetStandard()->JointPortTable(), aPartFormatID );

	RecordsetPtrWrap rs;
	if ( FAILED( rs.Set( strSource, *DataSourceConnection() ) ) ) return 0;
	if ( rs.GetRecordCount() == 0 ) return 0;
	
	JointPortFormerSource aJPFSource;
	JointPortFormer* aJPF = 0;
	jpfopf = new JointPortFormersOfPartFormat();
	
	while ( !rs.IsEOF() )
	{
		aJPFSource.Empty();
		aJPFSource.PartFormatID( rs.GetString( _T( "PF_ID" ) ) );
		aJPFSource.SerialNumber( rs.GetString( _T( "ID" ) ) );
		aJPFSource.JointPortFormatID( rs.GetString( _T( "JPF_ID" ) ) );
		aJPFSource.AddSizeRange( rs.GetString( _T( "Size_Range_1" ) ) );
		aJPFSource.AddSizeRange( rs.GetString( _T( "Size_Range_2" ) ) );
		aJPFSource.AddSizeRange( rs.GetString( _T( "Size_Range_3" ) ) );
		aJPFSource.AddSizeRange( rs.GetString( _T( "Size_Range_4" ) ) );
		aJPFSource.PositionRange( rs.GetString( _T( "Position_Range" ) ) );
		aJPFSource.DirectionRange( rs.GetString( _T( "Direction_Range" ) ) );
		aJPFSource.DefaultPosition( rs.GetString( _T( "Default_Position" ) ) );
		aJPFSource.JointFormatX( rs.GetString( _T( "Joint_Format_X" ) ) );
		aJPFSource.JointFormatZ( rs.GetString( _T( "Joint_Format_Z" ) ) );
		aJPFSource.AutoID( rs.GetInt( _T("Auto_ID") ) );
		rs.MoveNext();
		
		aJPF = new JointPortFormer;
		if ( !aJPF->EnlistBy( &aJPFSource ) )
		{
			delete aJPF;
			delete jpfopf;
			return 0;
		}
		else
		{
			jpfopf->Add( aJPF );
			InitPropertyStack(aJPFSource.AutoID(), aJPF);
		}
	}
	
	pf->JointPortFormers( jpfopf );
	return jpfopf;
}

_ConnectionPtr* PartFormat::DataSourceConnection() 
{ 
	return Manager()->DataSourceConnection();
}

JointPortFormersOfPartFormat* PartFormat::GetJointPortFormers() 
{ 
	return m_JointPortFormers ?
	m_JointPortFormers : ( m_JointPortFormers = Manager()->GetJointPortFormers( ID() ) ); 
}

DSItemManager::Iterator* PartFormat::GetDSItem() 
{ 
	return Manager()->GetDSItem( ID() ); 
}
	
PropertiesOfProductFormat* PartFormat::GetProperties() 
{ 
	return m_Properties ? m_Properties :
		m_Properties = Manager()->GetProperties( ID() ); 
}

BOOL PartFormatManager::InitPropertyStack(INT nID, JointPortFormer* pFormer)
{
	OriginalPropertySet set;

	ASSERT(Owner());
	ASSERT(Owner()->GetStandard());
	BOOL bResult = set.GetOriginalPropertySet(nID,
		Owner()->GetStandard()->JointPortPropertyTable(), Owner()->DataSourceURI());

	OriginalProperty* pOPr = set.GetFirst();
	while(pOPr != NULL)
	{
		PropertyVariable* pVar = pOPr->GenerateVariable();
		ASSERT(pVar);
		pFormer->GetPropertyStack().AddProperty(pVar);

		ASSERT(!pVar->Default().IsEmpty());
		SimpleExpression expr(pVar->Default(), &pFormer->GetPropertyStack());
		*pVar = (CString)expr.Caculate();

		pOPr = set.GetNext();
	}

	return TRUE;
}

}
